import { message, notification } from 'ant-design-vue'
import type { AxiosError } from 'axios'

export interface ErrorInfo {
  message: string
  code?: string | number
  details?: any
  timestamp: number
}

export class ErrorHandler {
  private static instance: ErrorHandler
  private errorHistory: ErrorInfo[] = []

  static getInstance(): ErrorHandler {
    if (!ErrorHandler.instance) {
      ErrorHandler.instance = new ErrorHandler()
    }
    return ErrorHandler.instance
  }

  // 处理HTTP错误
  handleHttpError(error: AxiosError): void {
    const errorInfo: ErrorInfo = {
      message: this.getHttpErrorMessage(error),
      code: error.response?.status,
      details: error.response?.data,
      timestamp: Date.now(),
    }

    this.logError(errorInfo)
    this.showErrorMessage(errorInfo)
  }

  // 处理业务错误
  handleBusinessError(error: any): void {
    const errorInfo: ErrorInfo = {
      message: error.message || '业务处理失败',
      code: error.code,
      details: error,
      timestamp: Date.now(),
    }

    this.logError(errorInfo)
    this.showErrorMessage(errorInfo)
  }

  // 处理未捕获的错误
  handleUncaughtError(error: Error): void {
    const errorInfo: ErrorInfo = {
      message: error.message || '未知错误',
      details: {
        stack: error.stack,
        name: error.name,
      },
      timestamp: Date.now(),
    }

    this.logError(errorInfo)
    this.showErrorNotification(errorInfo)
  }

  // 获取HTTP错误消息
  private getHttpErrorMessage(error: AxiosError): string {
    if (error.response) {
      const { status, data } = error.response
      
      // 优先使用服务器返回的错误消息
      if (data && typeof data === 'object' && 'message' in data) {
        return data.message as string
      }

      // 根据状态码返回默认消息
      switch (status) {
        case 400:
          return '请求参数错误'
        case 401:
          return '未授权，请重新登录'
        case 403:
          return '拒绝访问'
        case 404:
          return '请求的资源不存在'
        case 408:
          return '请求超时'
        case 409:
          return '请求冲突'
        case 422:
          return '请求参数验证失败'
        case 429:
          return '请求过于频繁，请稍后再试'
        case 500:
          return '服务器内部错误'
        case 502:
          return '网关错误'
        case 503:
          return '服务暂时不可用'
        case 504:
          return '网关超时'
        default:
          return `请求失败 (${status})`
      }
    } else if (error.request) {
      return '网络连接失败，请检查网络设置'
    } else {
      return '请求配置错误'
    }
  }

  // 显示错误消息
  private showErrorMessage(errorInfo: ErrorInfo): void {
    message.error(errorInfo.message)
  }

  // 显示错误通知
  private showErrorNotification(errorInfo: ErrorInfo): void {
    notification.error({
      message: '系统错误',
      description: errorInfo.message,
      duration: 5,
    })
  }

  // 记录错误
  private logError(errorInfo: ErrorInfo): void {
    console.error('Error:', errorInfo)
    
    // 添加到错误历史
    this.errorHistory.push(errorInfo)
    
    // 保持错误历史在合理范围内
    if (this.errorHistory.length > 50) {
      this.errorHistory = this.errorHistory.slice(-25)
    }

    // 在开发环境下可以发送错误到监控服务
    if (import.meta.env.DEV) {
      this.reportError(errorInfo)
    }
  }

  // 上报错误（可以集成到错误监控服务）
  private reportError(errorInfo: ErrorInfo): void {
    // 这里可以集成Sentry、Bugsnag等错误监控服务
    console.log('报告错误到监控服务:', errorInfo)
  }

  // 获取错误历史
  getErrorHistory(): ErrorInfo[] {
    return [...this.errorHistory]
  }

  // 清除错误历史
  clearErrorHistory(): void {
    this.errorHistory = []
  }
}

// 创建全局错误处理器实例
export const errorHandler = ErrorHandler.getInstance()

// 设置全局错误处理
export const setupGlobalErrorHandler = () => {
  // 处理未捕获的Promise错误
  window.addEventListener('unhandledrejection', (event) => {
    errorHandler.handleUncaughtError(new Error(event.reason))
    event.preventDefault()
  })

  // 处理未捕获的JavaScript错误
  window.addEventListener('error', (event) => {
    errorHandler.handleUncaughtError(event.error)
  })
}